import {type Datafeed, type SymbolInfo, type Period, type DatafeedWatchCallback, type KData, type GetKlineArgs} from "~/composables/types";
import {adjustFromTo} from "~/composables/dateutil";


/**
 * 使用Coingecko的免费API，无需秘钥，最小30m时间周期
 * 详细API文档：https://www.coingecko.com/zh/api/documentation
 * 这里固定为请求binance交易所，定价币是tether(USDT)
 *
 * coins/list  所有币的对应id
 * coins/markets 获取所有币种，id，图标，价格，市值；基于所有交易所
 * coins/{id}/tickers  获取某个交易所，所有币基于某个定价币usdt的行情
 * coins/{id}/ohlc  免费用户最小30m间隔，无历史数据
 *
 */
export default class CoingeckoDatafeed implements Datafeed{

  /**
   * coins/{id}/ohlc  免费用户最小30m间隔，无历史数据
   * 1 - 2 days: 30 minutes
   * 3 - 30 days: 4 hours
   * 31 days and beyond: 4 days
   * @param symbol
   * @param period
   * @param from
   * @param to
   */
  async getHistoryKLineData({symbol, period, from, to, strategy}: GetKlineArgs): Promise<KData> {
    let days = 1;
    if(period.timeframe === '4h'){
      days = 30
    }
    else if(period.timeframe === '4d'){
      days = 365
    }
    let qDeriod: Period = {timespan: 'day', multiplier: 1, timeframe: '1d', text: 'D', secs: 86400};
    const [okstart, okend] = adjustFromTo(qDeriod, new Date().getTime(), days)
    const min_start = okstart + (okend - okstart) * 0.1
    if(to <= min_start || from >= okend)return {data: []}
    const url = `https://api.coingecko.com/api/v3/coins/${symbol.ticker}/ohlc?vs_currency=usd&days=${days}`
    const response = await fetch(url, {
      headers: {'Access-Control-Allow-Origin': '*'}
    })
    const result = await response.json()
    const bars = await (result || []).map((data: any) => ({
      timestamp: data[0],
      open: data[1],
      high: data[2],
      low: data[3],
      close: data[4],
    }))
    return {data: bars}
  }

  /**
   * coins/{id}/tickers  获取某个交易所，所有币基于某个定价币usdt的行情
   * @param search
   */
  async getSymbols(): Promise<SymbolInfo[]> {
    // 这里固定参数，tether, binance
    const rsp = await fetch('https://api.coingecko.com/api/v3/coins/tether/tickers?exchange_ids=binance')
    const result = await rsp.json()
    return await (result.tickers || []).map((data: any) => ({
      ticker: data.coin_id,
      name: data.base,
      shortName: data.base,
      market: 'spot',
      exchange: data.market.identifier,
      priceCurrency: data.target,
      logo: ''
    }))
  }

  subscribe(symbol: SymbolInfo, period: Period, callback: DatafeedWatchCallback): void {
  }

  unsubscribe(symbol: SymbolInfo, period: Period): void {
  }

}
